﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using VncSharpExampleCS.Properties;
using Newtonsoft.Json;
using System.IO.Ports;
using System.Reflection;
using System.Net.Http;
using System.Net;
using AutoWindowsSize;
using System.Diagnostics.Eventing.Reader;
using System.Net.NetworkInformation;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using System.Runtime.InteropServices;


namespace VncSharpExampleCS
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }
        IniConfig ini = new IniConfig("./config.ini");
        private List<TcpClient> laserClients = new List<TcpClient>();
        List<PictureBox> LaserPictureList;
        List<PictureBox> waterBoxImageList;

        private List<(string ipAddress, int port, string name)> laserMachines;
        // 模板列表
        List<string> tempList;
        // 下拉框
        List<ComboBox> comboBoxes;
        // 计数label
        List<Label> countLabels;
        // 开始和结束按钮
        List<Button> startBtns;
        
        List<Button> lightBtns;
        List< GroupBox>  groupBoxes;


        string[] msg_type = new string[] { "初始", "初始", "初始", "初始", "初始", "初始" };

        AutoAdaptWindowsSize AutoSize;
        private object streamLock = new object(); // 流操作锁
        // 客户端状态
        // 创建串口
        private static SerialPort comm = new SerialPort();
        // 灯的状态
        static bool[] lightStates = new bool[4];

        int errrcvcnt = 0;
        // 串口号
        string serialCom = "";  
        private List<NetworkStream> laserStreams = new List<NetworkStream>();  // 客户端流
        private string PlcIp = "";
        //西门子PLC
        private SiemensS7Net siemensTcpNet;

        #region Plc点位
        private string laserAlarm1 = "M1.1";
        private string laserAlarm2 = "M1.2";
        private string laserAlarm3 = "M1.3";
        private string laserAlarm4 = "M1.4";
        private string laserAlarm5 = "M1.5";
        private string laserAlarm6 = "M1.6";
        private string waterBoxAlarm1 = "M2.1";
        private string waterBoxAlarm2 = "M2.2";
        private string waterBoxAlarm3 = "M2.3";
        private string resetSignal = "M3.0";
        private string isAlarmSignal = "M3.1";
        private List<string> laserAlarmList;
        private List<string> waterBoxAlarmList;



        #endregion






        private void Form1_Load(object sender, EventArgs e)
        {

            if (!HslCommunication.Authorization.SetAuthorizationCode("f44b3795-d88e-4d48-b7c9-d38e3c48441e"))
            {
                MessageBox.Show("授权失败！当前程序只能使用8小时！");
            }
            timer1.Start();
            timer2.Start();
            LaserPictureList = new List<PictureBox> { LaserPicture1, LaserPicture2, LaserPicture3, LaserPicture4, LaserPicture5, LaserPicture6 };
            waterBoxImageList = new List<PictureBox> { waterBoxImage1, waterBoxImage2, waterBoxImage3 };


            laserMachines = new List<(string, int, string)>
            {
                (ini.ReadKey("laser_ip1").Split(':')[0], Convert.ToInt32(ini.ReadKey("laser_ip1").Split(':')[1]),"1号"),
                (ini.ReadKey("laser_ip2").Split(':')[0], Convert.ToInt32(ini.ReadKey("laser_ip2").Split(':')[1]),"2号"),
                (ini.ReadKey("laser_ip3").Split(':')[0], Convert.ToInt32(ini.ReadKey("laser_ip3").Split(':')[1]),"3号"),
                (ini.ReadKey("laser_ip4").Split(':')[0], Convert.ToInt32(ini.ReadKey("laser_ip4").Split(':')[1]),"4号"),
                (ini.ReadKey("laser_ip5").Split(':')[0], Convert.ToInt32(ini.ReadKey("laser_ip5").Split(':')[1]),"5号"),
                (ini.ReadKey("laser_ip6").Split(':')[0], Convert.ToInt32(ini.ReadKey("laser_ip6").Split(':')[1]),"6号")
            };
            tempList = new List<string>
            {
                ini.ReadKey("template1"),ini.ReadKey("template2"),ini.ReadKey("template3"),ini.ReadKey("template4"),ini.ReadKey("template5"),ini.ReadKey("template6"),ini.ReadKey("template7"),ini.ReadKey("template8"),ini.ReadKey("template9")
            };

            comboBoxes = new List<ComboBox>
            {
                comboTemp1, comboTemp2, comboTemp3, comboTemp4, comboTemp5, comboTemp6
            };
            countLabels = new List<Label>
            {
                countLabel1, countLabel2, countLabel3, countLabel4, countLabel5, countLabel6
            };
            laserClients = new List<TcpClient>
            {
                new TcpClient(), new TcpClient(), new TcpClient(), new TcpClient(), new TcpClient(), new TcpClient()
            };
            startBtns = new List<Button>
            {
                startBtn1, startBtn2, startBtn3, startBtn4, startBtn5, startBtn6,
            };

            laserAlarmList = new List<string>
            {
                laserAlarm1, laserAlarm2, laserAlarm3, laserAlarm4, laserAlarm5, laserAlarm6
            };
            waterBoxAlarmList = new List<string>
            {
                waterBoxAlarm1, waterBoxAlarm2, waterBoxAlarm3
            };
            groupBoxes = new List<GroupBox>
            {
                groupBox_1, groupBox_2, groupBox_3, groupBox_4, groupBox_5, groupBox_6
            };



            for (int i = 0; i < comboBoxes.Count; i++)
            {
                comboBoxes[i].Items.AddRange(tempList[i].Split(','));
            }

            comboTempAll.Items.AddRange(ini.ReadKey("temp_all").Split(','));
            serialCom = ini.ReadKey("serialCom");
            PlcIp = ini.ReadKey("PlcIp");
            // 打开串口
            //OpenSerialPort();

            AutoSize = new AutoAdaptWindowsSize(this);
            for (int i = 0; i < 6; i++)
            {
                laserStreams.Add(null);
            }

            Task.Run(() => connectPlc());   // 连接PLC

        }


        // 连接激光机
        private async Task ConnectToLaserAsync(string ipAddress, int port)
        {
            try
            {
                TcpClient client = new TcpClient();
                await client.ConnectAsync(ipAddress, port);
                ShowMsg($"Connected to laser machine at {ipAddress}:{port}");
                laserClients.Add(client);
            }
            catch (Exception ex)
            {
                ShowMsg($"Failed to connect to laser machine at {ipAddress}:{port}. Error: {ex.Message}");
            }
        }
        // 发送信息给激光机
        //void SendMessageToLaserAsync(int laserIndex, string message)
        //{
        //    if (laserIndex < 0 || laserIndex >= laserClients.Count)
        //    {
        //        ShowMsg("Invalid laser index.");
        //        return;
        //    }

        //    var client = laserClients[laserIndex];
        //    if (client.Connected)
        //    {
        //        NetworkStream stream = client.GetStream();
        //        byte[] data = Encoding.UTF8.GetBytes(message);
        //        stream.WriteAsync(data, 0, data.Length);
        //        ShowMsg($"Sent message to laser {laserIndex}: {message}");
        //    }
        //    else
        //    {
        //        ShowMsg($" {laserMachines[laserIndex].name}没有连接.");
        //    }
        //}
        // 计时器
        private void timer1_Tick(object sender, EventArgs e)
        {

            for (int i = 0; i < laserClients.Count; i++)
            {
                string str = "GetCount;;";
                if (laserClients[i] != null && laserClients[i].Connected)
                {

                    SendMsg(laserClients[i], str);
                }
            }
            for (int i = 0; i < laserClients.Count; i++)
            {
                if (laserClients[i].Connected == true)
                {
                    LaserPictureList[i].Image = Resources.green_circle;
                }
                else
                {
                    LaserPictureList[i].Image = Resources.gray_circle;
                    countLabels[i].Text = "打印计数";
                }
            }





        }


        // 开始达标按钮
        private void startBtn_Click(object sender, EventArgs e)
        {
            Button startBtn = sender as Button;
            int index = startBtns.IndexOf(startBtn);
            string str = "";
            
            if (laserClients[index] != null && laserClients[index].Connected)
            {
                if (startBtn.Text == "开始打标" && laserClients[index] != null)
                {
                    str = "StartMark;;";
                    startBtn.Text = "关闭打标";
                    startBtn.BackColor = Color.FromArgb(87, 204, 153);
                    SendMsg(laserClients[index], str);
                }
                else
                {
                    str = "StopMark;;";
                    startBtn.Text = "开始打标";
                    startBtn.BackColor = Color.FromArgb(128, 128, 128);
                    SendMsg(laserClients[index], str);
                }

            }
            else
            {
                ShowMsg($"{laserMachines[index].name}打标失败，请检查是否连接");
            }

        }



        // 数据接收函数，处理每个客户端的数据接收
        // 修改后的 ConnectAndReceiveDataAsync 方法
        private async Task ConnectAndReceiveDataAsync(string serverAddress, int port, int serial)
        {
            try
            {
                await laserClients[serial].ConnectAsync(serverAddress, port);

                // 获取并保存流实例
                lock (streamLock)
                {
                    laserStreams[serial] = laserClients[serial].GetStream();
                }

                LaserPictureList[serial].Image = Resources.green_circle;
                ShowMsg($"{laserMachines[serial].name}连接成功");
                msg_type[serial] = "启动";

                byte[] buffer = new byte[1024];
                int bytesRead;

                // 使用全局的流实例
                while (true)
                {
                    try
                    {
                        bytesRead = await laserStreams[serial].ReadAsync(buffer, 0, buffer.Length);
                        if (bytesRead == 0) break; // 连接正常关闭

                        string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
                        ProcessReceivedData(receivedData, serverAddress, serial);
                    }
                    catch (IOException ex) when (ex.InnerException is SocketException se && se.SocketErrorCode == SocketError.ConnectionReset)
                    {
                        ShowMsg($"{laserMachines[serial].name}连接被重置");
                        break;
                    }
                }
            }
            catch (SocketException ex)
            {
                HandleSocketException(ex, serial);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("无法访问已释放的对象。"))
                {
                    Console.WriteLine($"{laserMachines[serial].name}发生错误: {ex.Message}");
                }
                else
                {
                    ShowMsg($"{laserMachines[serial].name}发生错误: {ex.Message}");
                }
                
            }
            finally
            {
                Disconnect(serial);
            }
        }


        // 新增数据处理方法
        private void ProcessReceivedData(string receivedData, string serverAddress, int serial)
        {
            if (receivedData.Contains("Ok"))
            {
                //ShowMsg($"{serverAddress}:【{msg_type[serial]}】状态{receivedData.Replace(";;", "")}");
            }
            else
            {
                string[] laser_counts = receivedData.Replace(";;", "").Split(',');
                if (laser_counts.Length >= 4)
                {
                    Invoke((MethodInvoker)delegate
                    {
                        countLabels[serial].Text =
                            $"总打标数：{laser_counts[0]}\r\n" +
                            $"当次打标数：{laser_counts[1]}";
                    });
                }
            }
        }
        // 修改后的Socket异常处理方法
        private void HandleSocketException(SocketException ex, int serial)
        {
            switch (ex.SocketErrorCode)
            {
                case SocketError.ConnectionRefused:
                    ShowMsg($"{laserMachines[serial].name}连接被拒绝");
                    break;
                case SocketError.TimedOut:
                    ShowMsg($"{laserMachines[serial].name}连接超时");
                    break;
                default:
                    ShowMsg($"{laserMachines[serial].name}网络错误: {ex.Message}");
                    break;
            }
        }

        //private async Task ConnectAndReceiveDataAsync(string serverAddress, int port,int serial)
        //{
        //    try
        //    {

        //        await laserClients[serial].ConnectAsync(serverAddress, port);
        //        //laserStreams[serial] = laserClients[serial].GetStream();
        //        LaserPictureList[serial].Image = Resources.green_circle;
        //        ShowMsg($"{laserMachines[serial].name}连接成功");
        //        msg_type[serial] = "启动"; 
        //        using (NetworkStream stream = laserClients[serial].GetStream())
        //        {
        //            byte[] buffer = new byte[1024];
        //            int bytesRead;

        //            while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) != 0)
        //            {
        //                // 将接收到的数据转换成字符串并显示
        //                string receivedData = Encoding.UTF8.GetString(buffer, 0, bytesRead);
        //                if (receivedData.Contains("Ok"))
        //                {
        //                    ShowMsg($"{serverAddress}:【{msg_type[serial]}】状态{receivedData.Replace(";;","")}");
        //                }
        //                else
        //                {
        //                    string[] laser_counts = receivedData.Replace(";;", "").Split(',');
        //                    countLabels[serial].Text = $"总打标数：{laser_counts[0]}  当次打标数：{laser_counts[1]}\r\n漏打次数：{laser_counts[2]}  打印耗时{laser_counts[3]}ms";
        //                }


        //                // 将字符串转换为动态对象
        //                //dynamic jsonObject = JsonConvert.DeserializeObject(receivedData);
        //                //string info = jsonObject.name;

        //                //switch (info)
        //                //{
        //                //    case "query-version":
        //                //        ShowMsg($"{laserMachines[serial].name}:版本号为：{jsonObject.value}");
        //                //        break;
        //                //    case "open-file":
        //                //        ShowMsg($"{laserMachines[serial].name}:选择模板为：{jsonObject.value}");
        //                //        break;
        //                //    case "executing-jobs":
        //                //        int status = jsonObject.status;
        //                //        switch (status)
        //                //        {
        //                //            case 0:
        //                //                if (jsonObject.value == 0)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:飞行打标，成功进入打标状态");
        //                //                }
        //                //                else if (jsonObject.value == 1)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:静态打标，成功进入打标状态");
        //                //                }
        //                //                break;
        //                //            case 1:
        //                //                if (jsonObject.value == 0)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:飞行打标，进入打标状态失败");
        //                //                }
        //                //                else if (jsonObject.value == 1)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:静态打标，进入打标状态失败");
        //                //                }
        //                //                break;
        //                //            case 2:
        //                //                if (jsonObject.value == 0)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:飞行打标，文件内容为空");
        //                //                }
        //                //                else if (jsonObject.value == 1)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:静态打标，文件内容为空");
        //                //                }
        //                //                break;
        //                //            case 3:
        //                //                if (jsonObject.value == 0)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:飞行打标，激光机报警");
        //                //                }
        //                //                else if (jsonObject.value == 1)
        //                //                {
        //                //                    ShowMsg($"{laserMachines[serial].name}:静态打标，激光机报警");
        //                //                }
        //                //                break;
        //                //        }
        //                //        break;
        //                //    case "finish-jobs":
        //                //        if (jsonObject.status == 0)
        //                //        {
        //                //            ShowMsg($"{laserMachines[serial].name}:成功停止打标，并离开打标状态；");
        //                //        }
        //                //        else if (jsonObject.status == 1)
        //                //        {
        //                //            ShowMsg($"{laserMachines[serial].name}:停止打标发生错误");
        //                //        }
        //                //        break;
        //                //    case "”remote-trigger":
        //                //        status = jsonObject.status;
        //                //        switch (status)
        //                //        {
        //                //            case 0:
        //                //                ShowMsg($"{laserMachines[serial].name}:触发成功；");
        //                //                break;
        //                //            case 1:
        //                //                ShowMsg($"{laserMachines[serial].name}:发生错误；");
        //                //                break;
        //                //            case 2:
        //                //                ShowMsg($"{laserMachines[serial].name}:打标机不在状态；");
        //                //                break;
        //                //        }
        //                //        break;
        //                //    case "query-info":
        //                //        status = jsonObject.status;
        //                //        switch (status)
        //                //        {
        //                //            case 0:
        //                //                countLabels[serial].Text = "打印计数：" + jsonObject.value.mark_count.ToString();
        //                //                break;
        //                //            case 1:
        //                //                ShowMsg($"{serverAddress}:获取状态信息失败；");
        //                //                break;
        //                //        }
        //                //        break;
        //                //}
        //                // 可以在这里处理收到的数据或发送响应
        //            }
        //        }
        //    }
        //    catch (SocketException ex)
        //    {
        //        if (ex.ErrorCode == 10061)
        //        {
        //            Console.WriteLine(ex.Message);
        //        }
        //        else
        //        {
        //            ShowMsg($"{laserMachines[serial].name}:{ex.Message}");
        //        }
        //    }
        //}
        // 关闭所有激光机
        private void button4_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < laserClients.Count; i++)
            {
                Disconnect(i);
                countLabels[i].Text = "打印计数：";


            }
        }

        // 关闭激光机
        public void Disconnect(int serial)
        {
            if (laserClients[serial].Connected)
            {
                try
                {
                    laserClients[serial].Close();
                    LaserPictureList[serial].Image = Resources.gray_circle;
                    ShowMsg($"激光机：{laserMachines[serial].name} 关闭成功。");
                }
                catch(Exception ex)
                {
                    ShowMsg(ex.Message);
                }
            }
            else
            {
                LaserPictureList[serial].Image = Resources.gray_circle;
                ShowMsg($"激光机：{laserMachines[serial].name} 已经关闭。");
            }
        }
        // 日志打印函数
        private void ShowMsg(string str)
        {
            txtLog.AppendText(DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss] ") + str + "\r\n");
            if (txtLog.Lines.Length > 1000) txtLog.Clear();
            // 后面添加了txt记录的功能
            string fileName = DateTime.Now.ToString("yyyy_MM_dd_") + "log.txt";
            using (StreamWriter writer = File.AppendText(fileName))
            {
                writer.WriteLine($"{DateTime.Now.ToString("[yyyy-MM-dd HH:mm:ss]")} - {str}");
            }
        }



        // 一键连接所有激光机
        private void button3_Click(object sender, EventArgs e)
        {
     
            //for (int i = 0;i< laserMachines.Count;i++) 
            for (int i = 0;i< laserClients.Count; i++) 
            {
                if (!laserClients[i].Connected)
                {
                    laserClients[i] = new TcpClient();
                    ConnectAndReceiveDataAsync(laserMachines[i].ipAddress, laserMachines[i].port, i);
                }
                
                
            }

        }
        
        

        // 点击图片后连接设备
        private void LaserPicture_Click(object sender, EventArgs e)
        {
            PictureBox laserPicture = sender as PictureBox;
            int index = LaserPictureList.IndexOf(laserPicture);
            
            if (laserClients[index].Connected == false)
            {
                laserClients[index].Close();
                laserClients[index] = new TcpClient();
                ConnectAndReceiveDataAsync(laserMachines[index].ipAddress, laserMachines[index].port, index);
                LaserPictureList[index].Image = Resources.green_circle;
                ShowMsg($"{laserMachines[index].name}:连接成功");
            }
            else
            {
                Disconnect(index);
            }
                
            
        }
        // 灯控制函数
        private void lightBtn_Click(object sender, EventArgs e)
        {
            Button light_btn = sender as Button;
            int index = lightBtns.IndexOf(light_btn);
            get_status();
            if (lightStates[index] == false)
            {
                open_close(index, true);
                
            }
            else{
              
                open_close(index, false);
                
                
            }
        }
        // 模板切换
        private void ComboTemp_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox comboBox = sender as ComboBox;
            int index = comboBoxes.IndexOf(comboBox);
            if (comboBox != null && laserClients[index].Connected)
            {
                // 获取按钮在列表中的索引
                string str = $"SwitchDoc,{comboBox.Text};;";
                SendMsg(laserClients[index],str);
                ShowMsg($"切换模板为{comboBox.Text}");
            }
            else
            {
                ShowMsg("设备未连接");
            }
        }
        private NetworkStream stream;
        private async void SendMsg(TcpClient sock, string str)
        {
            byte[] end = { 0x00 };
            var buffer = Encoding.UTF8.GetBytes(str);
            try
            {
                NetworkStream stream = sock.GetStream(); // 每次获取专属的 NetworkStream
                await stream.WriteAsync(buffer, 0, buffer.Length);
                
            }
            catch (Exception ex)
            {
                ShowMsg($"Error sending message: {ex.Message}");
            }
        }





        // 打开串口
        public bool OpenSerialPort()
        {

            //关闭时点击，则设置好端口，波特率后打开
            try
            {
                comm.PortName = serialCom; //串口名 COM1
                comm.BaudRate = int.Parse("9600"); //波特率  9600
                comm.DataBits = 8; // 数据位 8
                comm.ReadBufferSize = 4096;
                comm.StopBits = StopBits.One;
                comm.Parity = Parity.None;
                comm.Open();
                ShowMsg("串口打开成功");
            }
            catch (Exception ex)
            {

                //捕获到异常信息，创建一个新的comm对象，之前的不能用了。
                comm = new SerialPort();
                //现实异常信息给客户。
                MessageBox.Show(ex.Message);
                return false;
            }
            return true;
        }



        #region IO开关
        private byte[] sendinfo(byte[] info)
        {
            if (comm == null)
            {
                comm = new SerialPort();
                return null;
            }

            if (comm.IsOpen == false)
            {
                OpenSerialPort();
                return null;
            }
            try
            {
                byte[] data = new byte[2048];
                int len = 0;

                comm.Write(info, 0, info.Length);

                try
                {
                    Thread.Sleep(50);
                    Stream ns = comm.BaseStream;
                    ns.ReadTimeout = 50;
                    len = ns.Read(data, 0, 2048);

                }
                catch (Exception)
                {
                    return null;
                }
                errrcvcnt = 0;
                return analysisRcv(data, len);
            }
            catch (Exception)
            {

            }
            return null;
        }

        private byte[] analysisRcv(byte[] src, int len)
        {
            if (len < 6) return null;
            if (src[0] != Convert.ToInt16("254")) return null;

            switch (src[1])
            {
                case 0x01:
                    if (CMBRTU.CalculateCrc(src, src[2] + 5) == 0x00)
                    {
                        byte[] dst = new byte[src[2]];
                        for (int i = 0; i < src[2]; i++)
                            dst[i] = src[3 + i];
                        return dst;
                    }
                    break;
                case 0x02:
                    if (CMBRTU.CalculateCrc(src, src[2] + 5) == 0x00)
                    {
                        byte[] dst = new byte[src[2]];
                        for (int i = 0; i < src[2]; i++)
                            dst[i] = src[3 + i];
                        return dst;
                    }
                    break;
                case 0x04:
                    if (CMBRTU.CalculateCrc(src, src[2] + 5) == 0x00)
                    {
                        byte[] dst = new byte[src[2]];
                        for (int i = 0; i < src[2]; i++)
                            dst[i] = src[3 + i];
                        return dst;
                    }
                    break;
                case 0x05:
                    if (CMBRTU.CalculateCrc(src, 8) == 0x00)
                    {
                        byte[] dst = new byte[1];
                        dst[0] = src[4];
                        return dst;
                    }
                    break;
                case 0x0f:
                    if (CMBRTU.CalculateCrc(src, 8) == 0x00)
                    {
                        byte[] dst = new byte[1];
                        dst[0] = 1;
                        return dst;
                    }
                    break;
                case 0x06:
                    if (CMBRTU.CalculateCrc(src, 8) == 0x00)
                    {
                        byte[] dst = new byte[4];
                        dst[0] = src[2];
                        dst[1] = src[3];
                        dst[2] = src[4];
                        dst[3] = src[5];
                        return dst;
                    }
                    break;
                case 0x10:
                    if (CMBRTU.CalculateCrc(src, 8) == 0x00)
                    {
                        byte[] dst = new byte[4];
                        dst[0] = src[2];
                        dst[1] = src[3];
                        dst[2] = src[4];
                        dst[3] = src[5];
                        return dst;
                    }
                    break;
            }
            return null;
        }


        private void DebugInfo(string infotxt, byte[] info, int len = 0)
        {
            string debuginfo;
            StringBuilder builder = new StringBuilder();
            if (info != null)
            {
                if (len == 0) len = info.Length;
                //判断是否是显示为16禁止
                //依次的拼接出16进制字符串
                for (int i = 0; i < len; i++)
                {
                    builder.Append(info[i].ToString("X2") + " ");
                }
            }
            debuginfo = string.Format("{0}:{1}\r\n", infotxt, builder.ToString());
            builder.Clear();
        }

        private void get_status()
        {
            byte[] info = CModbusDll.ReadAIInfo(Convert.ToInt16("254"), 1000, 6);
            byte[] rst = sendinfo(info);

            if (rst == null) return;
            if (rst.Length != 12) return;
            ushort baseaddr = 0;
            ushort equipid = 0;
            byte[] dostatus = new byte[4];
            byte[] distatus = new byte[4];

            baseaddr = rst[0];
            baseaddr <<= 8;
            baseaddr |= rst[1];

            equipid = rst[2];
            equipid <<= 8;
            equipid |= rst[3];

            for (int i = 0; i < 4; i++)
            {
                dostatus[i] = rst[4 + i];
                distatus[i] = rst[8 + i];
            }
            int value = dostatus[0] - 240;
            Console.WriteLine($"转换后的值: {value}");

            // 判断每个灯的状态
            lightStates[0] = (value & 1) != 0; // 第一灯
            lightStates[1] = (value & 2) != 0; // 第二灯
            lightStates[2] = (value & 4) != 0; // 第三灯
            lightStates[3] = (value & 8) != 0; // 第四灯
        }
        // 关闭串口
        private void open_close(int serial, bool flag)
        {
            byte[] info = CModbusDll.WriteDO(Convert.ToInt16("254"), serial, flag);
            byte[] rst = sendinfo(info);
            if(rst != null && flag)
            {
                lightBtns[serial].BackColor = Color.Green;
            }
            else if(rst != null && !flag)
            {
                lightBtns[serial].BackColor = Color.Gray;
            }

        }

        #endregion


        #region 按钮
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult result = MessageBox.Show("您确定关闭当前界面吗?", "温馨提示", MessageBoxButtons.YesNo);
            if (result == DialogResult.No)
            {
                e.Cancel = true;
            }
            else
            {
                if (Application.OpenForms.Count == 0)
                    Application.Exit();
            }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            //if(comboTempAll.Text == "")
            //{
            //    MessageBox.Show("请选择模板后，进行打标。");
            //    return;
            //}
            string str = "";
            if (button5.Text == "开始打标")
            {
                for (int i = 0;i < laserClients.Count; i++)
                {
                    if (laserClients[i].Connected)
                    {
                        str = "StartMark;;";
                        SendMsg(laserClients[i], str);
                        startBtns[i].Text = "关闭打标";
                        startBtns[i].BackColor = Color.FromArgb(87, 204, 153);
                        string str2 = "SwitchDoc,green.bpd;;";
                        SendMsg(laserClients[i], str2);
                        ShowMsg("使用模板为：green.bpd");
                        label2.Text = "当前使用模板：green.bpd";
                    }
                    else
                    {
                        ShowMsg($"{laserMachines[i].name}打标失败，请检查连接");
                    }
                }
                button5.Text = "关闭打标";
                button5.BackColor = Color.FromArgb(87, 204, 153);


            }
            else
            {
                for (int i = 0; i < laserClients.Count; i++)
                {
                    if (laserClients[i].Connected)
                    {
                        str = "StopMark;;";
                        SendMsg(laserClients[i], str);
                        comboTempAll.SelectedIndex = 0;
                        startBtns[i].Text = "开始打标";
                        startBtns[i].BackColor = Color.FromArgb(128, 128, 128);
                        msg_type[i] = "开始打标";
                        label2.Text = "选择模板：green.bpd";

                    }
                }
                button5.Text = "开始打标";
                button5.BackColor = Color.FromArgb(128, 128, 128);
            }
        }

        private void comboTempAll_SelectedIndexChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < laserClients.Count; i++)
            {
                if (laserClients[i].Connected)
                {

                    // 获取按钮在列表中的索引

                    string str = $"SwitchDoc,{comboTempAll.Text};;";
                    SendMsg(laserClients[i], str);
                    comboBoxes[i].Text = comboTempAll.Text;
                    msg_type[i] = "模板切换";
                }
                else
                {
                    ShowMsg($"{laserMachines[i].name}模板失败，请检查连接");
                }
            }
            
        }
        form laser_form;
        private void button1_Click(object sender, EventArgs e)
        {
            if (laser_form == null || laser_form.IsDisposed)  // 如果 B 界面未创建或已被销毁
            {
                laser_form = new form();

            }

            laser_form.Show();
            laser_form.WindowState = FormWindowState.Normal; // 防止最小化后无法显示
            laser_form.Activate();  // 让 B 界面获得焦点
        }
        #endregion

        private void Form1_SizeChanged(object sender, EventArgs e)
        {
            if (AutoSize != null)
            {
                AutoSize.FormSizeChanged();
            }
        }


        #region PLC控制函数
        /// <summary>
        /// 连接PLC
        /// </summary>
        private void connectPlc()
        {
            siemensTcpNet = new SiemensS7Net(SiemensPLCS.S200Smart);
            siemensTcpNet.IpAddress = ini.ReadKey("plc_ip");
            siemensTcpNet.Port = int.Parse(ini.ReadKey("plc_port"));

            siemensTcpNet.ConnectClose();

            Thread.Sleep(50);

            try
            {
                OperateResult connect = siemensTcpNet.ConnectServer();
                if (connect.IsSuccess)
                {
                    ShowMsg("连接PLC成功");
                }
                else
                {
                    siemensTcpNet = null;
                    ShowMsg("连接PLC失败");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 断开PLC
        /// </summary>
        private void disconnectPlc()
        {
            if (siemensTcpNet == null) return;

            siemensTcpNet.ConnectClose();
        }
        private void WritePlcBool(string addr, bool value)
        {
            if (siemensTcpNet == null) return;

            OperateResult write = siemensTcpNet.Write(addr, value);
        }

        private bool ReadPlcBool(string key)
        {

            OperateResult<bool> result = siemensTcpNet.ReadBool(key);

            bool br = result.Content;

            return br;
        }

        private bool pingTest(string ip)
        {
            PingOptions pingOption = new PingOptions();
            pingOption.DontFragment = true;

            //Application.DoEvents();

            try
            {
                string data = "sendData:goodgoodgoodgoodgoodgood";
                byte[] buffer = Encoding.ASCII.GetBytes(data);
                int timeout = 120;
                Ping pingSender = new Ping();
                PingReply reply = pingSender.Send(ip, timeout, buffer);
                if (reply.Status == IPStatus.Success)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception)
            {
                return false;
            }

        }

        #endregion
        // 计时器
        private void timer2_Tick(object sender, EventArgs e)
        {
            if (pingTest(PlcIp))
            {
                OperateResult connectResult = siemensTcpNet.ConnectServer();
                if (!connectResult.IsSuccess)
                {
                    ShowMsg("PLC没有连接成功。");
                    return;
                }
            }
            else
            {
                ShowMsg("PLC没有网络连接。");
                return;
            }
            
            for (int i = 0; i < 6; i++)
            {
                if (ReadPlcBool(laserAlarmList[i])) // 如果设备故障
                {
                    groupBoxes[i].BackColor = Color.Red;
                }
                else
                {
                    groupBoxes[i].BackColor = Color.Transparent;
                }
            }

            for (int i = 0; i < 3; i++)
            {
                if (ReadPlcBool(waterBoxAlarmList[i])) // 如果设备故障
                {
                    waterBoxImageList[i].Image = Resources.red_circle; // 显示红色图片
                }
                else
                {
                    waterBoxImageList[i].Image = Resources.green_circle;
                }
            }

            
            WritePlcBool(isAlarmSignal,!alarmCheckBox.Checked); // 正常取反
            
        }

        private void resetBtn_Click(object sender, EventArgs e)
        {
            WritePlcBool(resetSignal, true);
        }

        private void plcImage_Click(object sender, EventArgs e)
        {
            OperateResult connectResult = siemensTcpNet.ConnectServer();
            if (!connectResult.IsSuccess)
            {
                Task.Run(() => connectPlc());
            }
        }
    }
}
